package studay.single;

/**
 * @program: 设计模式
 * @description: 单例设计模式 --（懒汉实现方式）
 * @author: Tom
 * @create: 2022-01-04 20:43
 **/
public class SingletonLazy {

    private static volatile SingletonLazy instance;

    /**
     * 构造函数私有化
     */
    private SingletonLazy(){}

    /**
     * 对外暴露一个方法获取类的对象
     * @return
     */
//    public static SingletonLazy getInstance(){
//        if(instance == null){
//            instance = new SingletonLazy();
//        }
//        return instance;
//    }

    /**
     * 采用synchronized加锁有很大性能开销
     * @return
     */
//    public static synchronized SingletonLazy getInstance(){
//        if(instance == null){
//            instance = new SingletonLazy();
//        }
//        return instance;
//    }

    /**
     * 第三种方式，存在线程安全问题
     * DCL双重检查锁定
     * 从内存模型角度来说不安全，因为 instance = new SingletonLazy();不是原子性操作
     * 1.分配内存控件
     * 2.在空间内创造对象
     * 3.将对象赋值给instance
     * 这三个在编译时候指令重排，多线程情况下可能出现问题，解决办法是增加volatile修饰，禁止指令重排
     * @return
     */
    public static SingletonLazy getInstance(){
        if(instance == null){
            synchronized (SingletonLazy.class) {
                if(instance == null) {
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }
}
